//
// Created by edward on 23-2-10.
//

#include "SpinLockMutex.h"
#include "utils.h"
#include <atomic>
#include <thread>
#include <vector>
#include <mutex>

using namespace std;

atomic<int> cnt = 0;
vector<int> arr;
edward::multithread::SpinLockMutex mtx;

constexpr int kMax = 20;

void populate_queue() {
    for (int i = 0; i < kMax; ++i) arr.push_back(i);
    cnt.store(kMax, std::memory_order_release);
}

void consume_queue(int n) {
    int idx;
    while (true) {
        if ((idx = cnt.fetch_sub(1, std::memory_order_acquire)) <= 0) {
            //this_thread::sleep_for(chrono::seconds(1));
        } else {
            lock_guard lk(mtx);
            edward::print(n, ":", arr[idx - 1]);
        }
    }
}

int main() {
    thread producer(populate_queue);
    thread consumer1(consume_queue, 1);
    thread consumer2(consume_queue, 2);
    producer.join();
    consumer1.join();
    consumer2.join();

    return 0;
}